package com.zm.utils;

import java.io.File;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Iterator;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.converters.BigDecimalConverter;
import org.apache.commons.beanutils.converters.ByteConverter;
import org.apache.commons.beanutils.converters.DoubleConverter;
import org.apache.commons.beanutils.converters.FloatConverter;
import org.apache.commons.beanutils.converters.IntegerConverter;
import org.apache.commons.beanutils.converters.LongConverter;
import org.apache.commons.beanutils.converters.ShortConverter;
import org.apache.commons.io.FilenameUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

/**
 * request 传入的实体bean 文件对象 文件前缀 文件保存路径
 * 
 * @author Ming
 *
 */
@Service("Myutils")
public class Myutils {
	public <T> T uploadFils(HttpServletRequest request, T t, MultipartFile part, String filePrefix, String filePath) {
		// 注册日期转换器：request参数中的日期类型字符串值则会使用该转换器进行转换为Date类型
		ConvertUtils.register(new Myconverter(), Date.class);
		/*
		 * 注册一下几个转换器：防止BeanUtils.setProperty()方法把null或者""的设值为0或者0.0
		 * 也就是：BeanUtils.setProperty()
		 * 给Integer、Short、Double、Float、Long、BigDecimal基本类型的值可以设置为null值，否则会设置默认值。
		 * 阻止BeanUtils.setProperty()方法把null值转换为默认值；
		 */
		ConvertUtils.register(new ByteConverter(null), Byte.class);
		ConvertUtils.register(new LongConverter(null), Long.class);
		ConvertUtils.register(new FloatConverter(null), Float.class);
		ConvertUtils.register(new ShortConverter(null), Short.class);
		ConvertUtils.register(new IntegerConverter(null), Integer.class);
		ConvertUtils.register(new DoubleConverter(null), Double.class);
		ConvertUtils.register(new BigDecimalConverter(null), BigDecimal.class);
		// 获得文件后缀
		String filrSuffix = FilenameUtils.getExtension(part.getOriginalFilename());
		// 重置文件名,防止文件重名
		String strFileName = filePrefix + "_" + System.currentTimeMillis() + "." + filrSuffix;
		// 准备文件上传的服务器的路径地址【要求是绝对地址】
		String strConPath = request.getServletContext().getRealPath("/");
		System.out.println(strConPath);
		// 组合上传地址 服务器绝对地址+用户定义相对路径
		String strRelPath = "static/" + filePath;
		String strUploadPath = strConPath + File.separatorChar + strRelPath;
		// 判断当前地址在服务器是否存在
		File file = new File(strUploadPath);
		if (!file.exists()) {
			// 如果不存在则创建该目录
			file.mkdirs();
		}
		// 获取表单中对应的name属性
		String formName = part.getName();
		// 将表单中的属性转换为bena中的属性
		String beanFileName = formName.replace("file_", "");
		try {
			// 将图片上传至服务器
			// 上传服务器地址，服务器绝对地址+用户定义相对路径+文件名
			part.transferTo(new File(strUploadPath + File.separatorChar + strFileName));
			// 将文件在服务器中的相对地址传入服务器中
			BeanUtils.setProperty(t, beanFileName, strRelPath + File.separatorChar + strFileName);

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return t;
	}

	/**
	 * 对多个文件进行保存
	 * 
	 * @param request
	 * @param t要进行处理的bean
	 * @param filePrefix文件的前缀
	 * @param filePath文件的保存路径
	 * @return 保存完所有文件的bean对象
	 */
	public <T> T uploadFils2(HttpServletRequest request, T t, String filePrefix, String filePath) {
		// 注册日期转换器：request参数中的日期类型字符串值则会使用该转换器进行转换为Date类型
		ConvertUtils.register(new Myconverter(), Date.class);
		/*
		 * 注册一下几个转换器：防止BeanUtils.setProperty()方法把null或者""的设值为0或者0.0
		 * 也就是：BeanUtils.setProperty()
		 * 给Integer、Short、Double、Float、Long、BigDecimal基本类型的值可以设置为null值，否则会设置默认值。
		 * 阻止BeanUtils.setProperty()方法把null值转换为默认值；
		 */
		ConvertUtils.register(new ByteConverter(null), Byte.class);
		ConvertUtils.register(new LongConverter(null), Long.class);
		ConvertUtils.register(new FloatConverter(null), Float.class);
		ConvertUtils.register(new ShortConverter(null), Short.class);
		ConvertUtils.register(new IntegerConverter(null), Integer.class);
		ConvertUtils.register(new DoubleConverter(null), Double.class);
		ConvertUtils.register(new BigDecimalConverter(null), BigDecimal.class);
		// 将当前上下文初始化给 CommonsMutipartResolver(MutipartResolver接口实现类)
		/** 百度 ***/
		CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getServletContext());
		// 检查request发送的form中是否有 enctype="multipart/form-data" 类型的二进制流媒体内容
		if (multipartResolver.isMultipart(request)) {
			// 有文件数据流上传
			// 将request进行转换为MultipartRequest，相当于可以处理文件的request（）然后进行处理
			MultipartRequest mr = (MultipartRequest) request;
			// 从request转到可以处理文件的MultipartRequest对象中获取所有的文件名
			Iterator<String> it = mr.getFileNames();
			// 依次将form表单中的所有文件对象取出
			while (it.hasNext()) {
				// 获取form表单中的文件名
				String FileName = it.next();
				System.out.println(FileName);
				// 通过文件名，获取文件对象,通过这一步，从request转到可以处理文件的MultipartRequest对象获取到了拥有当前文件对象的MultipartFile
				MultipartFile part = mr.getFile(FileName);
				if (part != null) {
					// 检查含有文件流的part部分进行处理
					// 使用part的ContentType来区分该part是包含文件流控件还是普通控件
					// 获取 MINE类型，普通控件的改属性是 null，文件上传控件的属性不是null
					String partContent = part.getContentType();
					// 判定文件控件是否上传了文件【判定有没有文件流对象】
					if (partContent != null && !partContent.equals("") && part.getSize() > 0) {
						// 获得文件后缀
						String filrSuffix = FilenameUtils.getExtension(part.getOriginalFilename());
						// 重置文件名,防止文件重名
						String strFileName = filePrefix + "_" + System.currentTimeMillis() + "." + filrSuffix;
						// 准备文件上传的服务器的路径地址【要求是绝对地址】
						String strConPath = request.getServletContext().getRealPath("/");
						System.out.println(strConPath);
						// 组合上传地址 服务器绝对地址+用户定义相对路径
						String strRelPath = "static/" + filePath;
						String strUploadPath = strConPath + File.separatorChar + strRelPath;
						// 判断当前地址在服务器是否存在
						File file = new File(strUploadPath);
						if (!file.exists()) {
							// 如果不存在则创建该目录
							file.mkdirs();
						}
						// 获取表单中对应的name属性
						String formName = part.getName();
						// 将表单中的属性转换为bena中的属性
						String beanFileName = formName.replace("file_", "");
						try {
							// 将图片上传至服务器
							// 上传服务器地址，服务器绝对地址+用户定义相对路径+文件名
							part.transferTo(new File(strUploadPath + File.separatorChar + strFileName));
							// 将文件在服务器中的相对地址传入服务器中
							BeanUtils.setProperty(t, beanFileName, strRelPath + File.separatorChar + strFileName);

						} catch (Exception e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				}
			}
		}

		return t;

	}
}
